package com.hoko.blur.view;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.multimodalinput.event.TouchEvent;

import com.hoko.blur.HokoBlur;
import com.hoko.blur.ResourceTable;
import com.hoko.blur.api.IBlurBuild;
import com.hoko.blur.api.IBlurProcessor;

import java.util.Optional;


/**
 * Created by yuxfzju on 16/8/20.
 */
public class DragBlurringView extends Component implements Component.DrawTask, Component.TouchEventListener {

    private static final int DOWNSAMPLE_FACTOR = 5;

    private float mOldX;
    private float mOldY;

    private Component mBlurredView;

    private PixelMap mToBlurBitmap;
    private Canvas mBlurringCanvas;
    private IBlurProcessor mProcessor;
    private IBlurProcessor blurBuild;

    private PixelMap backgroundPixMap;


    public DragBlurringView(Context context) {
        this(context,null);
    }

    public DragBlurringView(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
        addDrawTask(this);
        setTouchEventListener(this);
    }


    private void init() {
        mProcessor = HokoBlur.with(getContext())
                .scheme(HokoBlur.SCHEME_NATIVE)
                .mode(HokoBlur.MODE_GAUSSIAN)
                .radius(20)
                .sampleFactor(1.0f)
                .processor();
        blurBuild = HokoBlur.with(getContext())
            .forceCopy(true)
            .scheme(HokoBlur.SCHEME_NATIVE)
            .mode(HokoBlur.MODE_GAUSSIAN)
            .sampleFactor(1.0f)
            .radius(20)
            .processor();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (mBlurredView != null) {
            if (prepare()) {
                if (mBlurredView.getBackgroundElement() != null && mBlurredView.getBackgroundElement() instanceof ShapeElement) {
                      mToBlurBitmap.writePixels(Color.TRANSPARENT.getValue());
                } else {
                    mToBlurBitmap.writePixels(Color.TRANSPARENT.getValue());
                }
                mBlurredView.addDrawTask(new DrawTask() {
                    @Override
                    public void onDraw(Component component, Canvas canvas) {
                        canvas = mBlurringCanvas;
                    }
                });
                if(mToBlurBitmap!=null) {
                    PixelMap blurredBitmap = mProcessor.blur(mToBlurBitmap);
                    canvas.save();
                    canvas.translate(mBlurredView.getContentPositionX(), mBlurredView.getContentPositionY());
                    canvas.scale(DOWNSAMPLE_FACTOR, DOWNSAMPLE_FACTOR);
                    canvas.drawPixelMapHolder(new PixelMapHolder(blurredBitmap), 0, 0, new Paint());
                    canvas.restore();
                }
            }

        }

    }

    private boolean prepare() {
        final int width = mBlurredView.getWidth();
        final int height = mBlurredView.getHeight();
        if (mBlurringCanvas == null) {
            int scaledWidth = width / DOWNSAMPLE_FACTOR;
            int scaleHeight = height / DOWNSAMPLE_FACTOR;
            if (mToBlurBitmap == null) {
                PixelMap.InitializationOptions opt = new PixelMap.InitializationOptions();
                opt.size = new Size(scaledWidth,scaleHeight);
                opt.editable = true;
                opt.pixelFormat = PixelFormat.ARGB_8888;
                mToBlurBitmap = PixelMap.create(opt);
            }
            if (mToBlurBitmap == null) {
                return false;
            }

            mBlurringCanvas = new Canvas(new Texture(mToBlurBitmap));
            mBlurringCanvas.scale(1.0f / DOWNSAMPLE_FACTOR, 1.0f / DOWNSAMPLE_FACTOR);
        }

        return true;
    }


    public void setBlurredView(Component blurredView) {
        mBlurredView = blurredView;
    }
    public void setBlurredView(PixelMap PixelMap) {
        backgroundPixMap = PixelMap;
    }

    float oty,otx;
    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mOldX = touchEvent.getPointerScreenPosition(0).getX();
                mOldY =  touchEvent.getPointerScreenPosition(0).getY();

                 oty=getTranslationY();
                 otx=getTranslationX();
                return true;

            case TouchEvent.POINT_MOVE:
                float dx =touchEvent.getPointerScreenPosition(0).getX() -mOldX +otx;
                float dy = touchEvent.getPointerScreenPosition(0).getY()-mOldY+oty;
//                setMarginsLeftAndRight(10,10);
//                setMarginsTopAndBottom(50,50);
//                offsetLeftAndRight((int) dx);
//                offsetTopAndBottom((int) dy);
                setTranslation(dx,dy);
                invalidate();
                break;

            case TouchEvent.CANCEL:
            case TouchEvent.PRIMARY_POINT_UP:
                break;

        }
        return true;
    }
}
